import React from 'react';
import { message } from 'antd';
import UploadItem from "./item";
import { isReg } from './utils';
import styles from './style.moudle.scss';
import { PlusOutlined } from '@ant-design/icons';

type Props = {
  value?: string;
  maxSize: number;
  disabled?: boolean;
  regMessage?: string;
  maxUpload: number;
  regExp?: string | RegExp;
  onChange(url: string): any;
}

interface State {
  uploads: File[];
}

class UploadFile extends React.PureComponent<Props, State> {

  static defaultProps = {
    maxSize: 10,
    maxUpload: 1,
    disabled: false,
    onChange: () => null,
    regMessage: '上传文件类型不正确！'
  }

  state: State = {
    uploads: []
  }

  private inputFile = (
    React.createRef<HTMLInputElement>()
  );

  private checkSizePass = (file: File) => {
    const { maxSize } = this.props;
    const size = file.size / 1024 / 1024;
    return size > maxSize;
  }

  private getRegExp = (): RegExp => {
    const { regExp = '' } = this.props;
    return isReg(regExp) ? regExp : eval(regExp as string);
  }

  private checkFileType = (file: File) => {
    const { regExp } = this.props;
    if (!regExp) return true;
    return this.getRegExp().test(file.name);
  }

  private onFileChange = async (e: any) => {
    const {
      maxSize,
      regMessage
    } = this.props;
    const { uploads } = this.state;
    const { files = [] } = e.target;
    const file: File = files[0] || {};

    /*
    * 检查文件类型
    * */
    if (!this.checkFileType(file)) {
      return message.error(regMessage);
    }

    /*
    * 检查文件大小
    * */
    if (this.checkSizePass(file)) {
      return message.error(`上传文件不能大于${maxSize}M!`);
    }

    this.setState({ uploads: [...uploads, ...files] });
  }

  private onTrigger = () => {
    this.onClear();
    this.inputFile.current?.click?.();
  }

  private onClear = () => {
    const input = this.inputFile.current as any;
    input.value = null;
  }

  private getUrls = () => {
    const { value = '' } = this.props;
    return value.split('|').filter(v => v);
  }

  private setValue = (urls: string[]) => {
    return urls.join('|');
  }

  private onUploadSuccess = (url: string) => {
    const urls = this.getUrls();
    this.props?.onChange?.(this.setValue(urls.concat(url)));
  }

  private onDeleteItem = (file: File) => {
    const { uploads } = this.state;
    const index = uploads.findIndex((item: File) => item === file);
    if (index > -1) {
      const urls = this.getUrls();
      urls.splice(index, 1);
      uploads.splice(index, 1);
      this.setState({ uploads: [...uploads] });
      this.props?.onChange?.(this.setValue(urls));
    }
  }

  private renderTriggerButton = () => {
    const { uploads } = this.state;
    const { maxUpload } = this.props;
    if (uploads.length >= maxUpload) return null;
    const classList = [
      styles.trigger_button,
      'upload_item_error'
    ];
    if (maxUpload === 1) {
      classList.push(styles.upload_item_max);
    }
    return (
      <button
        type="button"
        onClick={this.onTrigger}
        disabled={this.props.disabled}
        className={classList.join(' ')}
      >
        <PlusOutlined/>
        <span className={styles.trigger_text}>
          点击上传
        </span>
      </button>
    )
  }

  render() {
    const { uploads } = this.state;
    return (
      <div className={styles.upload_items}>
        <input
          type="file"
          ref={this.inputFile}
          style={{ display: 'none' }}
          onChange={this.onFileChange}
        />
        {this.renderTriggerButton()}
        {uploads.map((file: File, i: number) => {
          return (
            <UploadItem
              key={i}
              file={file}
              onDelete={this.onDeleteItem}
              onSuccess={this.onUploadSuccess}
            />
          )
        })}
      </div>
    )
  }
}

export default UploadFile;
